﻿using Api.Shared.Model;
using Api.Shared.Utils.MyClient;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using KxApp.Chart;
using KxApp.Utils;
using KxApp.Views;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.Logging;
using System.Net.Http;
using System.Text.Json;
using System.Windows;
using static Api.Shared.Utils.MyCopyProperty;
using ApiData = KxApp.Chart.ApiData;

namespace KxApp.ViewModels
{
    [ExposedService(Lifetime.Singleton)]
    public partial class MainViewModel : ObservableObject
    {
        private readonly ChartView chartView;
        private readonly TableView tableView;
        private readonly OpcTestView opcTestView;
        private readonly DeviceView deviceView;
        private readonly ChartService chartService;
        private readonly IHttpClientFactory clientFactory;
        private readonly ILogger<MainViewModel> logger;
        private readonly IDeviceService deviceService;
        private readonly ApiData apiData;
        private readonly ScanView scanView;
        private CancellationTokenSource cts = new();
        private double d = 0.0;
        private HubConnection? hubConnection;
        private WebSocketTest webSocketTest = new();

        private async void InitSignalR()
        {
            hubConnection = new HubConnectionBuilder()
                .WithUrl("http://localhost:8889/MyHub")
                .WithAutomaticReconnect(new[]
                {
                    TimeSpan.Zero,                // 第一次重连立即尝试
                    TimeSpan.FromSeconds(2),      // 第二次重连2秒后
                    TimeSpan.FromSeconds(5),      // 第三次重连5秒后
                    TimeSpan.FromSeconds(10)      // 第四次及以后重连10秒后
                })
                .Build();

            var options = new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                WriteIndented = true
            };

            hubConnection.On<string>("ReceiveRandomNumber", (message) =>
            {
                try
                {
                    var wsTest = JsonSerializer.Deserialize<WebSocketTest>(message, options);
                    if (wsTest != null)
                    {
                        webSocketTest = wsTest;
                        Txt = $"WebSocketTest反序列化成功: {wsTest}";
                        logger.LogInformation($"SignalR收到WebSocketTest消息: {message}");
                    }
                    else
                    {
                        logger.LogInformation($"SignalR收到消息: {message}");
                    }
                }
                catch (Exception ex)
                {
                    logger.LogError($"WebSocketTest反序列化失败: {ex.Message}");
                }
                Txt = webSocketTest.TestFloat1.ToString();
                logger.LogInformation($"SignalR收到消息: {message}");
            });

            hubConnection.Closed += async (error) =>
            {
                logger.LogWarning("SignalR连接已关闭，尝试重连...");
                while (true)
                {
                    try
                    {
                        await Task.Delay(5000); // 5秒后重试
                        await hubConnection.StartAsync();
                        logger.LogInformation("SignalR重连成功");
                        break;
                    }
                    catch (Exception ex)
                    {
                        logger.LogError($"SignalR重连失败: {ex.Message}");
                    }
                }
            };

            try
            {
                await hubConnection.StartAsync();
                logger.LogInformation("SignalR连接成功");
            }
            catch (Exception ex)
            {
                logger.LogError($"SignalR连接失败: {ex.Message}");
            }
        }

        [ObservableProperty]
        private string txt = string.Empty;

        [ObservableProperty]
        private object? myContent = new();

        public MainViewModel(ChartView chartView, TableView tableView, OpcTestView opcTestView, DeviceView deviceView, ChartService chartService, IHttpClientFactory clientFactory, ILogger<MainViewModel> logger, IDeviceService deviceService, Chart.ApiData apiData, ScanView scanView)
        {
            this.chartView = chartView;
            this.tableView = tableView;
            this.opcTestView = opcTestView;
            this.deviceView = deviceView;
            this.chartService = chartService;
            this.clientFactory = clientFactory;
            this.logger = logger;
            this.deviceService = deviceService;
            this.apiData = apiData;
            this.scanView = scanView;
            MyContent = scanView;
            //Txt = "MainView";



            
            //GetApi();


            //InitSignalR();
        }

        private void GetApi()
        {
            ApiData data = new();
            Task.Factory.StartNew(async () =>
            {
                while (!cts.IsCancellationRequested)
                {
                    await Task.Delay(200);
                    try
                    {
                        using HttpClient? client = clientFactory.CreateClient();
                        client.Timeout = TimeSpan.FromSeconds(20);

                        var baseRequest = new BaseRequest
                        {
                            Method = HttpMethod.Get,
                            Route = $"/api/private/v1/Plc/Test3",
                        };
                        //MyHttpClient myHttpClient = new(ip, client);
                        MyHttpClient myHttpClient = new(client, "myIp");
                        var res = await myHttpClient.ExecuteAsync<ApiData>(baseRequest);


                        if (res.Result == null)
                        {
                            logger.LogError("WebApi没有运行!");
                        }
                        else
                        {
                            data = res.Result;
                            //double.TryParse(data.Short1.ToString("F2"), out double double1);
                            //double.TryParse(data.Short2.ToString("F2"), out double double2);
                            //double.TryParse(data.Short3.ToString("F2"), out double double3);
                            double.TryParse(data.Short16.ToString("F2"), out double double4);

                            //double.TryParse(data.Short20.ToString("F2"), out double double5);
                            //double.TryParse(data.Short21.ToString("F2"), out double double6);
                            //double.TryParse(data.Short17.ToString("F2"), out double double7);


                            //apiData = data;
                            //myData.E = double5;

                            CopyProperties(data, apiData);

                            //deviceService.Kr500v1.CurrentValue = apiData.Float1.ToString(
                            //    "0.00"
                            //);
                            //deviceService.Kr500v2.CurrentValue = apiData.Float2.ToString(
                            //    "0.00"
                            //);
                            deviceService.Kr500Pgno.CurrentValue = apiData.Short11.ToString();
                            deviceService.Kr500PdctId.CurrentValue = apiData.Short13.ToString();

                            //deviceService.Kr16v1.CurrentValue = apiData.Float3.ToString("0.00");
                            //deviceService.Kr16v2.CurrentValue = apiData.Float4.ToString("0.00");
                            deviceService.Kr16Pgno.CurrentValue = apiData.Short12.ToString();
                            deviceService.Kr16PdctId.CurrentValue = apiData.Short13.ToString();

                            deviceService.Kr500.State = apiData.Short1;
                            deviceService.Kr16.State = apiData.Short2;
                            deviceService.DZ1Servo.State = apiData.Short3;
                            deviceService.DZ2Servo.State = apiData.Short4;
                            deviceService.DZ3Servo.State = apiData.Short5;
                            deviceService.KJ1Servo.State = apiData.Short6;
                            deviceService.KJ2Servo.State = apiData.Short7;
                            deviceService.KJ3Servo.State = apiData.Short8;
                            deviceService.AxisServo.State = apiData.Short9;
                            deviceService.PolishServo.State = apiData.Short10;
                            deviceService.Camera.State = apiData.Short17;

                            deviceService.Kr500v1.CurrentValue = apiData.Float1015.ToString();

                            deviceService.Kr500v2.CurrentValue = apiData.Float1016.ToString();

                            deviceService.Kr500v3.CurrentValue = apiData.Float1017.ToString();

                            deviceService.Kr500v4.CurrentValue = apiData.Float1018.ToString();

                            deviceService.Kr500v5.CurrentValue = apiData.Float1019.ToString();

                            deviceService.Kr500v6.CurrentValue = apiData.Float1020.ToString();

                            deviceService.Kr500v7.CurrentValue = apiData.Float1021.ToString();

                            deviceService.Kr16v1.CurrentValue = apiData.Float108.ToString();

                            deviceService.Kr16v2.CurrentValue = apiData.Float109.ToString();

                            deviceService.Kr16v3.CurrentValue = apiData.Float1010.ToString();

                            deviceService.Kr16v4.CurrentValue = apiData.Float1011.ToString();

                            deviceService.Kr16v5.CurrentValue = apiData.Float1012.ToString();

                            deviceService.Kr16v6.CurrentValue = apiData.Float1013.ToString();

                            deviceService.Kr16v7.CurrentValue = apiData.Float1014.ToString();

                            deviceService.CameraX.CurrentValue = apiData.Float5.ToString(
                                "0.00"
                            );
                            deviceService.CameraY.CurrentValue = apiData.Float6.ToString(
                                "0.00"
                            );

                            deviceService.DZ1ActPos.CurrentValue = apiData.Float7.ToString(
                                "0.00"
                            );
                            deviceService.DZ1SetPos.CurrentValue = apiData.Float8.ToString(
                                "0.00"
                            );
                            deviceService.DZ1ActVel.CurrentValue = apiData.Float9.ToString(
                                "0.00"
                            );

                            deviceService.DZ2ActPos.CurrentValue = apiData.Float10.ToString(
                                "0.00"
                            );
                            deviceService.DZ2SetPos.CurrentValue = apiData.Float11.ToString(
                                "0.00"
                            );
                            deviceService.DZ2ActVel.CurrentValue = apiData.Float12.ToString(
                                "0.00"
                            );

                            deviceService.DZ3ActPos.CurrentValue = apiData.Float13.ToString(
                                "0.00"
                            );
                            deviceService.DZ3SetPos.CurrentValue = apiData.Float14.ToString(
                                "0.00"
                            );
                            deviceService.DZ3ActVel.CurrentValue = apiData.Float15.ToString(
                                "0.00"
                            );

                            deviceService.KJ1ActPos.CurrentValue = apiData.Float16.ToString(
                                "0.00"
                            );
                            deviceService.KJ1SetPos.CurrentValue = apiData.Float17.ToString(
                                "0.00"
                            );
                            deviceService.KJ1ActVel.CurrentValue = apiData.Float18.ToString(
                                "0.00"
                            );

                            deviceService.KJ2ActPos.CurrentValue = apiData.Float19.ToString(
                                "0.00"
                            );
                            deviceService.KJ2SetPos.CurrentValue = apiData.Float20.ToString(
                                "0.00"
                            );
                            deviceService.KJ2ActVel.CurrentValue = apiData.Float21.ToString(
                                "0.00"
                            );

                            deviceService.KJ3ActPos.CurrentValue = apiData.Float22.ToString(
                                "0.00"
                            );
                            deviceService.KJ3SetPos.CurrentValue = apiData.Float23.ToString(
                                "0.00"
                            );
                            deviceService.KJ3ActVel.CurrentValue = apiData.Float24.ToString(
                                "0.00"
                            );

                            deviceService.AxisActPos.CurrentValue = apiData.Float25.ToString(
                                "0.00"
                            );
                            deviceService.AxisSetPos.CurrentValue = apiData.Float26.ToString(
                                "0.00"
                            );
                            deviceService.AxisActVel.CurrentValue = apiData.Float27.ToString(
                                "0.00"
                            );

                            deviceService.PolishActPos.CurrentValue = apiData.Float28.ToString(
                                "0.00"
                            );
                            deviceService.PolishSetPos.CurrentValue = apiData.Float29.ToString(
                                "0.00"
                            );
                            deviceService.PolishActVel.CurrentValue = apiData.Float30.ToString(
                                "0.00"
                            );

                            deviceService.ProductData.ProductName = apiData.Str1;
                            deviceService.ProductData.ProductType = apiData.Short14;
                            deviceService.ProductData.ProductLength = apiData.Float31.ToString(
                                "0.00"
                            );
                            deviceService.ProductData.ProductWidth = apiData.Float32.ToString(
                                "0.00"
                            );
                            deviceService.ProductData.PolishPos1 = apiData.Float101.ToString(
                                "0.00"
                            );
                            deviceService.ProductData.PolishPos2 = apiData.Float102.ToString(
                                "0.00"
                            );
                            deviceService.ProductData.PolishPos3 = apiData.Float103.ToString(
                                "0.00"
                            );
                            deviceService.ProductData.PolishPos4 = apiData.Float104.ToString(
                                "0.00"
                            );

                            #region Chart

                            var Float1023 = apiData.Float1023.ToString("0.00");
                            var Float1024 = apiData.Float1024.ToString("0.00");
                            double.TryParse(Float1023, out var float1023);
                            double.TryParse(Float1024, out var float1024);


                            d += 0.1;
                            //myData.D = double4;
                            //myData.D = d;
                            chartService.LineValue1 = apiData.Float105;
                            chartService.LineValue2 = apiData.Float106;
                            chartService.LineValue3 = apiData.Float107;



                            //chartService.PieValue1 = float1023;
                            //chartService.PieValue2 = float1024;
                            chartService.PieValue1 = 92;
                            chartService.PieValue2 = 8;

                            chartService.BarValue1 = apiData.Short104;
                            //chartService.BarValue2 = apiData.Short105;
                            //chartService.BarValue3 = apiData.Short106;
                            //chartService.BarValue4 = apiData.Short107;
                            //chartService.BarValue5 = apiData.Short108;

                            //chartService.BarValue1 = 20;
                            chartService.BarValue2 = 25;
                            chartService.BarValue3 = 30;
                            chartService.BarValue4 = 35;
                            chartService.BarValue5 = 40;

                            chartService.BarValue11 = 50;
                            chartService.BarValue21 = 60;
                            chartService.BarValue31 = 70;
                            chartService.BarValue41 = 80;
                            chartService.BarValue51 = 90;

                            //chartService.PieValue1 = apiData.Short104;
                            //chartService.PieValue2 = apiData.Short105;
                            //chartService.PieValue3 = apiData.Short106;
                            //chartService.PieValue4 = apiData.Short107;
                            //chartService.PieValue5 = apiData.Short108;

                            //chartService.BarValue1 = apiData.Float1023;
                            //chartService.BarValue2 = apiData.Float1024;
                            //chartService.BarValue3 = apiData.Short103;
                            //chartService.BarValue4 = apiData.Short103;

                            chartService.GaugeValue = apiData.Short102;

                            #endregion


                            chartService.UpdateBarData();
                            chartService.UpdateLineData();
                            chartService.UpdatePieData();
                            chartService.UpdateBarData1();
                            //chartService.UpdateBarData();
                            //chartService.UpdateLineData();
                            //chartService.UpdatePieData();
                        }

                    }
                    catch (Exception ex)
                    {
                        logger.LogError($"{ex.Message}");
                    }
                }
            }, cts.Token,
                TaskCreationOptions.LongRunning,
                TaskScheduler.Default);
        }

        //[RelayCommand]
        //public void MaxNormal(Window window)
        //{
        //    window.WindowState =
        //        (window.WindowState == WindowState.Maximized)
        //            ? WindowState.Normal
        //            : WindowState.Maximized;
        //}

        public RelayCommand<Window> MaxNormalCommand =>
            new RelayCommand<Window>(
                (args) =>
                {
                    if (args is not Window window)
                    {
                        return;
                    }
                    window.WindowState =
                        (window.WindowState == WindowState.Maximized)
                            ? WindowState.Normal
                            : WindowState.Maximized;
                }
            );


        /// <summary>
        /// 参照myGit中MyCode程序
        /// </summary>
        /// <param name="str"></param>
        [RelayCommand]
        public void SwitchPage(string str)
        {
            switch (str)
            {
                case "TcpServer":
                    MyContent = tableView;
                    break;
                //case "TcpClient":
                //    MyContent = tcpClientView;
                //    break;

                //case "opcPage":
                //    MyContent = opcView;
                //    break;
                case "ReportPage":
                    MyContent = chartView;
                    break;
                case "opcPage":
                    MyContent = opcTestView;
                    break;
                case "Scan":
                    MyContent = scanView;
                    break;
                case "Md":
                    MyContent = deviceView;
                    break;
                //case "SolidWorks":
                //    MyContent = swView;
                //    break;
                default:
                    MyContent = scanView;
                    break;
            }
        }
    }
}
